#include "dyn_roots_bisection.h"

Bisection::Bisection(Functor &func, double initial, double end, double scan, double tol, int Nmax)
    : function(func)
{
    setInitialValue(initial);
    setEndPoint(end);
    setScanningSpeed(scan);
    setTolerance(tol);
    setMaxIterations(Nmax);
}

/*! We define the actual numerical algorithm.
 * It returns 0 if it's successful and 1
 * if the algorithm failed to converge within the
 * maximum number of iterations.
 */
int Bisection::solve()
{
    // We start the timer
    start = clock();

    // We set the root to the initial value.
    // The next part will update its value.
    root = initialValue;

    // We initialize the starting points and the return code
    double a = initialValue;
    double b = initialValue + scanningSpeed;
    int returnCode(1);

    for (int i=0;i<maxIterations;i++)
    {
        iterations++;
        // If the function is zero at the starting point,
        // we have found the root!
        if (function(a)==0 || function(b)==0)
        {
            root = a;
            returnCode = 0;
        }

        if (b>endPoint)
        {
            root = a;
            break;
        }

        if (function(a)*function(b)<0.0)
        {
            scanningSpeed /= 2;
            b = a + scanningSpeed;
            root = a;
        }
        else
        {
            a = b;
            b += scanningSpeed;
            continue;
        }

        if (scanningSpeed < tolerance)
        {
            root = a;
            returnCode = 0;
            break;
        }
    }
    end = clock();
    processorTime = ((double) (end-start))/ CLOCKS_PER_SEC;
    return returnCode;
}
